home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_68 / ctv-mod.asm < prev    next >
Assembly Source File  |  1995-01-01  |  26KB  |  1,363 lines

  1.        PAGE   60,132
  2.        TITLE  Sound Blaster (Killer Card) Object Module
  3.        SUBTTL Main Program
  4.  
  5.  
  6. if1
  7.     ifdef small
  8.          %OUT   Small Model
  9.     else
  10.          %OUT   Large Model
  11.     endif
  12. endif
  13.  
  14.  
  15.  
  16. ifdef    small
  17.     _TEXT  SEGMENT  WORD PUBLIC 'CODE'
  18.     _TEXT  ENDS
  19. else
  20.     CTV_TEXT  SEGMENT  WORD PUBLIC 'CODE'
  21.     CTV_TEXT  ENDS
  22. endif
  23.  
  24.  
  25. _DATA  SEGMENT  WORD PUBLIC 'DATA'
  26. _DATA  ENDS
  27. CONST  SEGMENT  WORD PUBLIC 'CONST'
  28. CONST  ENDS
  29. _BSS   SEGMENT  WORD PUBLIC 'BSS'
  30. _BSS   ENDS
  31.  
  32.  
  33. DGROUP GROUP   CONST, _BSS, _DATA
  34.  
  35. ifdef  small
  36.        ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
  37. else
  38.        ASSUME  CS: CTV_TEXT, DS: DGROUP, SS: DGROUP
  39. endif
  40.  
  41.  
  42.        PUBLIC      _io_addx, _intr_num, _voice_status
  43.        PUBLIC      _ctv_detect, _ctv_speaker, _ctv_output,
  44.        PUBLIC      _ctv_halt
  45.        PUBLIC      _ctv_pause, _ctv_continue, _ctv_uninstall
  46.        PUBLIC      _ctv_card_here
  47.  
  48.  
  49.  
  50.  
  51. _DATA  SEGMENT  WORD PUBLIC 'DATA'
  52.  
  53. ifdef  small
  54.        ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
  55. else
  56.        ASSUME  CS: CTV_TEXT, DS: DGROUP, SS: DGROUP
  57. endif
  58.  
  59. _io_addx       DW   220H
  60. _intr_num      DB   0
  61. _voice_status  DW   0
  62.  
  63. ORG_INT_ADDX       LABEL     DWORD
  64. ORG_INT2_ADDX      LABEL     DWORD
  65.   ORG_INT2_OFF      DW       ?
  66.   ORG_INT2_SEG      DW       ?
  67. ORG_INT3_ADDX      LABEL     DWORD
  68.   ORG_INT3_OFF      DW       ?
  69.   ORG_INT3_SEG      DW       ?
  70. ORG_INT5_ADDX      LABEL     DWORD
  71.   ORG_INT5_OFF      DW       ?
  72.   ORG_INT5_SEG      DW       ?
  73. ORG_INT7_ADDX      LABEL     DWORD
  74.   ORG_INT7_OFF      DW       ?
  75.   ORG_INT7_SEG      DW       ?
  76.  
  77.  
  78. ;---------------------
  79. ;      DMA DATA      |
  80. ;---------------------
  81. DMA_CURRENT_PAGE    DB       ?
  82. DMA_CURRENT_ADDX    DW       ?
  83. DMA_CURRENT_COUNT   DW       ?
  84. PAGE_TO_DMA         DB       ?
  85. LEN_L_TO_DMA        DW       ?
  86. LEN_H_TO_DMA        DW       ?
  87. LAST_DMA_OFFSET     DW       ?
  88.  
  89.  
  90. _DATA  ENDS
  91.  
  92.  
  93. ifdef  small
  94.     _TEXT  SEGMENT     WORD PUBLIC 'CODE'
  95. else
  96.     CTV_TEXT  SEGMENT     WORD PUBLIC 'CODE'
  97. endif
  98.  
  99.        SUBTTL    DSP module
  100.  
  101. WAIT_TIME        EQU    0200H
  102. DMA_VOICE_IN     EQU    45H
  103. DMA_VOICE_OUT    EQU    49H
  104.  
  105. DSP_ID_CMD              EQU    0E0H
  106. DSP_VER_CMD             EQU    0E1H
  107. DSP_VI8_CMD             EQU    24H
  108. DSP_VO8_CMD             EQU    14H
  109. DSP_VO2_CMD             EQU    17H
  110. DSP_VO4_CMD             EQU    75H
  111. DSP_VO25_CMD            EQU    77H
  112. DSP_MDAC1_CMD           EQU    61H
  113. DSP_MDAC2_CMD           EQU    62H
  114. DSP_MDAC3_CMD           EQU    63H
  115. DSP_MDAC4_CMD           EQU    64H
  116. DSP_MDAC5_CMD           EQU    65H
  117. DSP_MDAC6_CMD           EQU    66H
  118. DSP_MDAC7_CMD           EQU    67H
  119. DSP_TIME_CMD            EQU    40H
  120. DSP_SILENCE_CMD         EQU    80H
  121. DSP_PAUSE_DMA_CMD       EQU    0D0H
  122. DSP_ONSPK_CMD           EQU    0D1H
  123. DSP_OFFSPK_CMD          EQU    0D3H
  124. DSP_CONT_DMA_CMD        EQU    0D4H
  125. DSP_INTRQ_CMD           EQU    0F2H
  126.  
  127. CMS_TEST_CODE            EQU         0C6H
  128. RESET_TEST_CODE          EQU         0AAH
  129.  
  130. CMS_EXIST                EQU         1
  131. FM_MUSIC_EXIST           EQU         2
  132. CTV_VOICE_EXIST          EQU         4
  133.  
  134. FM_WAIT_TIME             EQU         40H
  135.  
  136.  
  137. WRITE_DSP_TIME   PROC
  138.  
  139.        PUSH   CX
  140.  
  141.        MOV    CX,WAIT_TIME
  142.        MOV    AH,AL
  143.  
  144. WDT10:
  145.        IN     AL,DX
  146.        OR     AL,AL
  147.        JNS    WDT20
  148.  
  149.        LOOP   WDT10
  150.  
  151.        STC
  152.        JMP    SHORT WDT90
  153.  
  154. WDT20:
  155.        MOV    AL,AH
  156.        OUT    DX,AL
  157.        CLC
  158.  
  159. WDT90:
  160.        POP    CX
  161.        RET
  162.  
  163. WRITE_DSP_TIME   ENDP
  164.  
  165.  
  166.  
  167. READ_DSP_TIME    PROC
  168.  
  169.        PUSH   CX
  170.        PUSH   DX
  171.  
  172.        MOV    DX,_io_addx
  173.        ADD    DL,0EH
  174.  
  175.        MOV    CX,WAIT_TIME
  176.  
  177. RDT10:
  178.        IN     AL,DX
  179.        OR     AL,AL
  180.        JS     RDT20
  181.  
  182.        LOOP   RDT10
  183.        STC
  184.        JMP    SHORT RDT90
  185.  
  186. RDT20:
  187.        SUB    DL,4
  188.        IN     AL,DX
  189.        CLC
  190.  
  191. RDT90:
  192.        POP    DX
  193.        POP    CX
  194.        RET
  195.  
  196. READ_DSP_TIME    ENDP
  197.  
  198.  
  199. WRITE_DSP   PROC
  200.  
  201.        MOV    AH,AL
  202.        MOV    AL,0F0H
  203.  
  204. WD10:
  205.        IN     AL,DX
  206.        OR     AL,AL
  207.        JS     WD10
  208.  
  209.        MOV    AL,AH
  210.        OUT    DX,AL
  211.        RET
  212.  
  213. WRITE_DSP   ENDP
  214.  
  215.  
  216.  
  217. READ_DSP    PROC
  218.  
  219.        PUSH   DX
  220.  
  221.        MOV    DX,_io_addx
  222.        ADD    DL,0EH
  223.        SUB    AL,AL
  224.  
  225. RD10:
  226.        IN     AL,DX
  227.        OR     AL,AL
  228.        JNS    RD10
  229.  
  230.        SUB    DL,4
  231.        IN     AL,DX
  232.  
  233.        POP    DX
  234.        RET
  235.  
  236. READ_DSP    ENDP
  237.  
  238.  
  239. RESET_DSP     PROC
  240.  
  241.        MOV    DX,_io_addx
  242.        ADD    DL,6
  243.        MOV    AL,1
  244.        OUT    DX,AL
  245.  
  246.        IN     AL,DX
  247. RDSP05:
  248.        INC    AL
  249.        JNZ    RDSP05
  250.  
  251.        OUT    DX,AL
  252.  
  253.        MOV    CL,20H
  254.  
  255. RDSP10:
  256.        CALL   READ_DSP_TIME
  257.        CMP    AL,0AAH
  258.        JE     RDSP20
  259.  
  260.        DEC    CL
  261.        JNZ    RDSP10
  262.        MOV    AX,2
  263.        JMP    SHORT RDSP90
  264.  
  265. RDSP20:
  266.        SUB    AX,AX
  267.  
  268. RDSP90:
  269.        OR     AX,AX
  270.        RET
  271.  
  272. RESET_DSP     ENDP
  273.  
  274.  
  275. VERIFY_IO_CHK      PROC
  276.  
  277.        MOV    BX,2
  278.  
  279.        MOV    AL,DSP_ID_CMD
  280.        MOV    DX,_io_addx
  281.        ADD    DX,0CH
  282.        CALL   WRITE_DSP_TIME
  283.        JC     VIO90
  284.  
  285.        MOV    AL,0AAH
  286.        CALL   WRITE_DSP_TIME
  287.        JC     VIO90
  288.  
  289.        CALL   READ_DSP_TIME
  290.        JC     VIO90
  291.  
  292.        CMP    AL,055H
  293.        JNE    VIO90
  294.  
  295.        SUB    BX,BX
  296.  
  297. VIO90:
  298.        MOV    AX,BX
  299.        OR     AX,AX
  300.        RET
  301.  
  302. VERIFY_IO_CHK      ENDP
  303.  
  304.  
  305. VERIFY_INTR        PROC
  306.  
  307.        MOV    AL,2
  308.        MOV    DX,OFFSET DUMMY_DMA_INT2
  309.        MOV    BX,OFFSET DGROUP:ORG_INT2_ADDX
  310.        CALL   SETUP_INTERRUPT
  311.  
  312.        MOV    AL,3
  313.        MOV    DX,OFFSET DUMMY_DMA_INT3
  314.        MOV    BX,OFFSET DGROUP:ORG_INT3_ADDX
  315.        CALL   SETUP_INTERRUPT
  316.  
  317.        MOV    AL,5
  318.        MOV    DX,OFFSET DUMMY_DMA_INT5
  319.        MOV    BX,OFFSET DGROUP:ORG_INT5_ADDX
  320.        CALL   SETUP_INTERRUPT
  321.  
  322.        MOV    AL,7
  323.        MOV    DX,OFFSET DUMMY_DMA_INT7
  324.        MOV    BX,OFFSET DGROUP:ORG_INT7_ADDX
  325.        CALL   SETUP_INTERRUPT
  326.  
  327.        MOV    _intr_num,0
  328.  
  329.        MOV    DX,_io_addx
  330.        ADD    DX,0CH
  331.        MOV    AL,DSP_INTRQ_CMD
  332.        CALL   WRITE_DSP
  333.  
  334.  
  335.  
  336.        SUB    AX,AX
  337.        MOV    CX,WAIT_TIME*4
  338.  
  339. VI10:
  340.        CMP    _intr_num,0
  341.        JNZ    VI90
  342.  
  343.        LOOP   VI10
  344.  
  345.        MOV    AX,3
  346.  
  347. VI90:
  348.        PUSH   AX
  349.  
  350.        MOV    AL,2
  351.        MOV    BX,OFFSET DGROUP:ORG_INT2_ADDX
  352.        CALL   RESTORE_INTERRUPT
  353.  
  354.        MOV    AL,3
  355.        MOV    BX,OFFSET DGROUP:ORG_INT3_ADDX
  356.        CALL   RESTORE_INTERRUPT
  357.  
  358.        MOV    AL,5
  359.        MOV    BX,OFFSET DGROUP:ORG_INT5_ADDX
  360.        CALL   RESTORE_INTERRUPT
  361.  
  362.        MOV    AL,7
  363.        MOV    BX,OFFSET DGROUP:ORG_INT7_ADDX
  364.        CALL   RESTORE_INTERRUPT
  365.  
  366.        POP    AX
  367.  
  368.        OR      AX,AX
  369.        RET
  370.  
  371. VERIFY_INTR        ENDP
  372.  
  373.  
  374. CHK_DSP_VERSION    PROC
  375.  
  376.        MOV    AL,DSP_VER_CMD
  377.        MOV    DX,_io_addx
  378.        ADD    DL,0CH
  379.        CALL   WRITE_DSP
  380.        CALL   READ_DSP
  381.        MOV    AH,AL
  382.        CALL   READ_DSP
  383.  
  384.        MOV    BX,1
  385.        CMP    AX,101H
  386.        JB     CDV90
  387.  
  388.        SUB    BX,BX
  389.  
  390. CDV90:
  391.        MOV    AX,BX
  392.        OR     AX,AX
  393.        RET
  394.  
  395. CHK_DSP_VERSION    ENDP
  396.  
  397.  
  398.  
  399. PAUSE_DSP_DMA     PROC
  400.  
  401.        PUSHF
  402.  
  403.        MOV    AH,DSP_PAUSE_DMA_CMD
  404.        MOV    BX,OFFSET DGROUP:_voice_status
  405.        SUB    CX,CX
  406.        MOV    DX,_io_addx
  407.        ADD    DL,0CH
  408.  
  409. PDD10:
  410.        STI
  411.        CMP    CX,[BX]
  412.        JE     PDD90
  413.  
  414.        CLI
  415.        IN     AL,DX
  416.        OR     AL,AL
  417.        JNS    PDD10
  418.  
  419. PDD20:
  420.        IN     AL,DX
  421.        OR     AL,AL
  422.        JS     PDD20
  423.  
  424.        MOV    AL,AH
  425.        OUT    DX,AL
  426.  
  427. PDD90:
  428.        POPF
  429.        RET
  430.  
  431. PAUSE_DSP_DMA     ENDP
  432.  
  433.  
  434.        SUBTTL    DMA module
  435.  
  436.  
  437. ;--------------------------------------------
  438. ; entry: DH = dma mode                      :
  439. ;        DL = page                          :
  440. ;        AX = current addx                  :
  441. ;        CX = current count                 :
  442. ;--------------------------------------------
  443.  
  444.     DMA_ADDX_REG        EQU    02H
  445.     DMA_COUNT_REG       EQU    03H
  446.     DMA_MASK_REG        EQU    0AH
  447.     DMA_MODE_REG        EQU    0BH
  448.     DMA_FF_REG          EQU    0CH
  449.     DMA_PAGE_REG        EQU    83H
  450.  
  451. PROG_DMA      PROC
  452.  
  453.        PUSH   BX
  454.  
  455.        MOV    BX,AX
  456.  
  457.        MOV    AL,5
  458.        OUT    DMA_MASK_REG,AL
  459.  
  460.        SUB    AL,AL
  461.        OUT    DMA_FF_REG,AL
  462.  
  463.        MOV    AL,DH
  464.        OUT    DMA_MODE_REG,AL
  465.  
  466.        MOV    AL,BL
  467.        OUT    DMA_ADDX_REG,AL
  468.  
  469.        MOV    AL,BH
  470.        OUT    DMA_ADDX_REG,AL
  471.  
  472.        MOV    AL,CL
  473.        OUT    DMA_COUNT_REG,AL
  474.  
  475.        MOV    AL,CH
  476.        OUT    DMA_COUNT_REG,AL
  477.  
  478.        MOV    AL,DL
  479.        OUT    DMA_PAGE_REG,AL
  480.  
  481.        MOV    AL,1
  482.        OUT    DMA_MASK_REG,AL
  483.  
  484.        POP    BX
  485.        RET
  486.  
  487. PROG_DMA      ENDP
  488.  
  489.  
  490. CALC_20BIT_ADDX    PROC
  491.  
  492.        PUSH   CX
  493.  
  494.        MOV    CL,4
  495.        ROL    DX,CL
  496.        MOV    CX,DX
  497.        AND    DX,0FH
  498.        AND    CX,0FFF0H
  499.        ADD    AX,CX
  500.        ADC    DX,0
  501.  
  502.        POP    CX
  503.        RET
  504.  
  505. CALC_20BIT_ADDX    ENDP
  506.  
  507.  
  508. ;-------------------------------------------------
  509. ; entry: AL = INTERRUPT NUM                      |
  510. ;        DX = new vector ofs, seg is alway CS    |
  511. ;        BX = offset of store buffer             :
  512. ;-------------------------------------------------
  513. SETUP_INTERRUPT    PROC
  514.  
  515.        PUSH   BX
  516.        PUSH   CX
  517.        PUSH   DX
  518.  
  519.        CLI
  520.  
  521.        MOV    CL,AL                    ; preserve interrupt number for use
  522.  
  523.        ADD    AL,8                     ; calculate interrupt vector addx
  524.        CBW
  525.        SHL    AL,1
  526.        SHL    AL,1
  527.        MOV    DI,AX
  528.  
  529.        PUSH   ES                       ; setup and preserve interrupt
  530.        SUB    AX,AX
  531.        MOV    ES,AX
  532.        MOV    AX,ES:[DI]
  533.        MOV    [BX],AX
  534.        MOV    ES:[DI],DX
  535.  
  536.        MOV    AX,ES:[DI+2]
  537.        MOV    [BX+2],AX
  538.        MOV    ES:[DI+2],CS
  539.  
  540.        POP    ES
  541.  
  542.        MOV    AH,1                     ; enable interrupt control mask-bit
  543.        SHL    AH,CL
  544.        NOT    AH
  545.  
  546.        IN     AL,21H
  547.        AND    AL,AH
  548.        OUT    21H,AL
  549.  
  550.        STI
  551.  
  552.        POP    DX
  553.        POP    CX
  554.        POP    BX
  555.        RET
  556.  
  557. SETUP_INTERRUPT    ENDP
  558.  
  559.  
  560. ;-------------------------------------------------
  561. ; entry: AL = INTERRUPT NUM                      |
  562. ;        BX = offset to stored addx              |
  563. ;-------------------------------------------------
  564. RESTORE_INTERRUPT  PROC
  565.  
  566.        CLI
  567.  
  568.        MOV    CL,AL
  569.  
  570.        ADD    AL,8                      ; calculate interrupt vector addx
  571.        CBW
  572.        SHL    AL,1
  573.        SHL    AL,1
  574.        MOV    DI,AX
  575.  
  576.        PUSH   ES                       ; restore interrupt vector
  577.        SUB    AX,AX
  578.        MOV    ES,AX
  579.        MOV    AX,[BX]
  580.        MOV    ES:[DI],AX
  581.  
  582.        MOV    AX,[BX+2]
  583.        MOV    ES:[DI+2],AX
  584.  
  585.        POP    ES
  586.  
  587.        MOV    AH,1
  588.        SHL    AH,CL
  589.  
  590.        IN     AL,21H
  591.        OR     AL,AH
  592.        OUT    21H,AL
  593.  
  594.        STI
  595.        RET
  596.  
  597. RESTORE_INTERRUPT  ENDP
  598.  
  599.  
  600. DUMMY_DMA_INT2      PROC   FAR
  601.  
  602.        PUSH   DX
  603.        MOV    DL,2
  604.        JMP    SHORT DUMMY_DMA_ISR
  605.  
  606. DUMMY_DMA_INT2      ENDP
  607.  
  608.  
  609. DUMMY_DMA_INT3      PROC   FAR
  610.  
  611.        PUSH   DX
  612.        MOV    DL,3
  613.        JMP    SHORT DUMMY_DMA_ISR
  614.  
  615. DUMMY_DMA_INT3      ENDP
  616.  
  617.  
  618. DUMMY_DMA_INT5      PROC   FAR
  619.  
  620.        PUSH   DX
  621.        MOV    DL,5
  622.        JMP    SHORT DUMMY_DMA_ISR
  623.  
  624. DUMMY_DMA_INT5      ENDP
  625.  
  626.  
  627. DUMMY_DMA_INT7      PROC   FAR
  628.  
  629.        PUSH   DX
  630.        MOV    DL,7
  631.  
  632. DUMMY_DMA_ISR:
  633.  
  634.        PUSH   DS
  635.        PUSH   AX
  636.  
  637.        MOV    AX,DGROUP
  638.        MOV    DS,AX
  639.  
  640.        MOV    _intr_num,DL
  641.  
  642.        MOV    DX,_io_addx
  643.        ADD    DX,0EH
  644.        IN     AL,DX
  645.  
  646.        MOV    AL,20H
  647.        OUT    20H,AL
  648.  
  649.        POP    AX
  650.        POP    DS
  651.        POP    DX
  652.        IRET
  653.  
  654. DUMMY_DMA_INT7      ENDP
  655.  
  656.  
  657.  
  658. DMA_OUT_INTR    PROC
  659.  
  660.        PUSH   DS
  661.        PUSH   ES
  662.        PUSH   AX
  663.        PUSH   BX
  664.        PUSH   CX
  665.        PUSH   DX
  666.        PUSH   DI
  667.        PUSH   SI
  668.        PUSH   BP
  669.  
  670.        CLD
  671.        MOV    AX,DGROUP
  672.        MOV    DS,AX
  673.        MOV    ES,AX
  674.  
  675.        MOV    DX,_io_addx
  676.        ADD    DL,0EH
  677.        IN     AL,DX
  678.  
  679.        MOV    AX,LEN_L_TO_DMA
  680.        OR     AX,AX
  681.        JNZ    VO_INT10
  682.  
  683.        CALL   END_DMA_TRANSFER
  684.  
  685.        JMP    SHORT VO_INT90
  686.  
  687. VO_INT10:
  688.        CALL   DMA_OUT_TRANSFER
  689.  
  690. VO_INT90:
  691.        MOV    AL,20H
  692.        OUT    20H,AL
  693.  
  694.        POP    BP
  695.        POP    SI
  696.        POP    DI
  697.        POP    DX
  698.        POP    CX
  699.        POP    BX
  700.        POP    AX
  701.        POP    ES
  702.        POP    DS
  703.        IRET
  704.  
  705. DMA_OUT_INTR    ENDP
  706.  
  707.  
  708.  
  709. DMA_OUT_TRANSFER     PROC
  710.  
  711.        MOV    CX,0FFFFH                ; get current page end address
  712.  
  713.        CMP    PAGE_TO_DMA,0            ; last page to dma ?
  714.        JNZ    DOT10                    ; no, skip
  715.  
  716.        INC    PAGE_TO_DMA
  717.        MOV    CX,LAST_DMA_OFFSET       ; get end addx
  718.  
  719. DOT10:
  720.        SUB    CX,DMA_CURRENT_ADDX      ; calcutate current page addx
  721.        MOV    DMA_CURRENT_COUNT,CX
  722.        INC    CX
  723.        JZ     DOT20
  724.  
  725.        SUB    LEN_L_TO_DMA,CX
  726.        SBB    LEN_H_TO_DMA,0
  727.        JMP    SHORT DOT30
  728.  
  729. DOT20:                  
  730.        DEC    LEN_H_TO_DMA
  731.  
  732. DOT30:
  733.        MOV    DH,DMA_VOICE_OUT
  734.        MOV    DL,DMA_CURRENT_PAGE
  735.        MOV    AX,DMA_CURRENT_ADDX
  736.        MOV    CX,DMA_CURRENT_COUNT
  737.        CALL   PROG_DMA
  738.  
  739.        DEC    PAGE_TO_DMA
  740.        INC    DMA_CURRENT_PAGE
  741.        MOV    DMA_CURRENT_ADDX,0
  742.  
  743.        MOV    CX,DMA_CURRENT_COUNT
  744.  
  745.        MOV    DX,_io_addx
  746.        ADD    DL,0CH
  747.  
  748.        MOV    AL,DSP_VO8_CMD
  749.        CALL   WRITE_DSP
  750.  
  751.        MOV    AL,CL
  752.        CALL   WRITE_DSP
  753.  
  754.        MOV    AL,CH
  755.        CALL   WRITE_DSP
  756.  
  757. DOT90:
  758.        RET
  759.  
  760. DMA_OUT_TRANSFER     ENDP
  761.  
  762.  
  763.  
  764. END_DMA_TRANSFER     PROC
  765.  
  766.        MOV    AL,5
  767.        OUT    DMA_MASK_REG,AL
  768.  
  769.        MOV    AL,_intr_num
  770.        MOV    BX,OFFSET DGROUP:ORG_INT_ADDX
  771.        CALL   RESTORE_INTERRUPT
  772.  
  773.        MOV    _voice_status,0
  774.  
  775.        MOV    DX,_io_addx
  776.        ADD    DL,0EH
  777.        IN     AL,DX
  778.  
  779.        RET
  780.  
  781. END_DMA_TRANSFER     ENDP
  782.  
  783.  
  784. ;---------------------------------------
  785. ;  WAIT_FM_STATUS                      :
  786. ;   entry:    AL = status to wait      :
  787. ;                  3 msb is concern    :
  788. ;   exit :    AX destroy               :
  789. ;             carry set for fail       :
  790. ;             carry clr for pass       :
  791. ;---------------------------------------
  792. WAIT_FM_STATUS     PROC
  793.  
  794.        PUSH   CX
  795.        PUSH   DX
  796.  
  797.        MOV    CX,FM_WAIT_TIME
  798.  
  799.        MOV    AH,AL
  800.        AND    AH,0E0H                  ; only 3 msb are FM status
  801.        MOV    DX,_io_addx
  802.        ADD    DL,8
  803.  
  804. WFS10:
  805.        IN     AL,DX
  806.        AND    AL,0E0H
  807.        CMP    AH,AL
  808.        JE     WFS20
  809.  
  810.        LOOP   WFS10
  811.  
  812.        STC
  813.        JMP    SHORT WFS90
  814.  
  815. WFS20:
  816.        CLC
  817.  
  818. WFS90:
  819.        POP    DX
  820.        POP    CX
  821.        RET
  822.  
  823. WAIT_FM_STATUS     ENDP
  824.  
  825.  
  826. ;---------------------------------------
  827. ;  WRITE_FM                            :
  828. ;   entry:    AH = data value          :
  829. ;             AL = addx value          :
  830. ;   exit :    AX destroy               :
  831. ;             DX destroy               :
  832. ;---------------------------------------
  833. WRITE_FM         PROC
  834.  
  835.        MOV    DX,_io_addx
  836.        ADD    DL,8
  837.        OUT    DX,AL
  838.        CALL   FM_DELAY
  839.        MOV    AL,AH
  840.        INC    DX
  841.        OUT    DX,AL
  842.        CALL   FM_DELAY
  843.        RET
  844.  
  845. WRITE_FM         ENDP
  846.  
  847.  
  848. FM_DELAY         PROC
  849.  
  850.        PUSH   AX
  851.        PUSH   DX
  852.  
  853.        MOV    DX,_io_addx
  854.        ADD    DL,8
  855.  
  856.        IN     AL,DX
  857.        IN     AL,DX
  858.        IN     AL,DX
  859.        IN     AL,DX
  860.        IN     AL,DX
  861.  
  862.        POP    DX
  863.        POP    AX
  864.  
  865.        RET
  866.  
  867. FM_DELAY         ENDP
  868.  
  869.  
  870.  
  871.  
  872.  
  873. ifdef  small
  874.     _ctv_detect      PROC
  875. else
  876.     _ctv_detect      PROC    FAR
  877. endif
  878.        PUSH   DS
  879.        PUSH   ES
  880.        PUSH   DI
  881.        PUSH   SI
  882.  
  883.        MOV    AX,DGROUP
  884.        MOV    DS,AX
  885.        MOV    ES,AX
  886.  
  887.        CALL   RESET_DSP
  888.        JNZ    ID90
  889.  
  890.        CALL   VERIFY_IO_CHK
  891.        JNZ    ID90
  892.  
  893.        CALL   CHK_DSP_VERSION
  894.        JNZ    ID90
  895.  
  896.        CALL   VERIFY_INTR
  897.        JNZ    ID90
  898.  
  899.        MOV    AL,1                     ; on speaker
  900.        CALL   ON_OFF_SPEAKER
  901.  
  902.        SUB    AX,AX
  903.  
  904. ID90:
  905.        POP    SI
  906.        POP    DI
  907.        POP    ES
  908.        POP    DS
  909.        RET
  910.  
  911. _ctv_detect      ENDP
  912.  
  913.  
  914. SPK_STK          STRUC
  915.  
  916. ifdef    small
  917.                    DW      ?
  918. else
  919.                    DD      ?
  920. endif
  921.  
  922.                    DW      ?
  923.     SPK_FLAG       DW      ?
  924.  
  925. SPK_STK          ENDS
  926.  
  927.  
  928. ifdef  small
  929.     _ctv_speaker     PROC
  930. else
  931.     _ctv_speaker     PROC    FAR
  932. endif
  933.  
  934.        PUSH   BP
  935.        MOV    BP,SP
  936.  
  937.        PUSH   DS
  938.  
  939.        MOV    AX,DGROUP
  940.        MOV    DS,AX
  941.  
  942.        MOV    AX,[BP+SPK_FLAG]
  943.        CALL   ON_OFF_SPEAKER
  944.  
  945.  
  946.        POP    DS
  947.  
  948.        POP    BP
  949.        RET
  950.  
  951. _ctv_speaker  ENDP
  952.  
  953.  
  954. ON_OFF_SPEAKER     PROC
  955.  
  956.  
  957.        MOV    DX,_io_addx
  958.        ADD    DX,0CH
  959.  
  960.        MOV    AH,DSP_ONSPK_CMD
  961.        OR     AL,AL
  962.        JNZ    OOS10
  963.  
  964.        MOV    AH,DSP_OFFSPK_CMD
  965.  
  966. OOS10:
  967.        MOV    AL,AH
  968.        CALL   WRITE_DSP
  969.  
  970.        SUB    AX,AX                    ; inidcate no error
  971.        RET
  972.  
  973. ON_OFF_SPEAKER     ENDP
  974.  
  975.  
  976.  
  977. OUT_STK       STRUC
  978.  
  979. ifdef  small
  980.            DW      ?                   ; one word ret addx
  981. else                                                      
  982.            DD      ?                   ; double word ret addx
  983. endif
  984.                    DW   ?
  985.     BUF_OFF        DW   ?
  986.     BUF_SEG        DW   ?
  987.     COUNT          DW   ?
  988.     SAMPLING       DW   ?
  989.  
  990. OUT_STK       ENDS
  991.  
  992.  
  993. ifdef  small
  994.     _ctv_output      PROC
  995. else
  996.     _ctv_output      PROC    FAR
  997. endif
  998.  
  999.        PUSH   BP
  1000.        MOV    BP,SP
  1001.  
  1002.        PUSH   DS
  1003.        PUSH   ES
  1004.        PUSH   DI
  1005.        PUSH   SI
  1006.  
  1007.        MOV    AX,DGROUP
  1008.        MOV    DS,AX
  1009.        MOV    ES,AX
  1010.  
  1011.        CMP    _voice_status,0
  1012.        JZ     OV10
  1013.  
  1014.        MOV    AX,1
  1015.        JMP    SHORT OV90
  1016.  
  1017. OV10:
  1018.        MOV    _voice_status,1
  1019.  
  1020.        MOV    DX,_io_addx
  1021.        ADD    DL,0CH
  1022.  
  1023.        MOV    DX,0FH                   ; calculate sampling rate value for
  1024.        MOV    AX,4240H                 ; DSP
  1025.        MOV    CX,[BP+SAMPLING]
  1026.        DIV    CX
  1027.  
  1028.        MOV    CL,AL
  1029.        NEG    CL
  1030.  
  1031.        MOV    DX,_io_addx
  1032.        ADD    DL,0CH
  1033.        MOV    AL,DSP_TIME_CMD
  1034.        CALL   WRITE_DSP
  1035.  
  1036.        MOV    AL,CL
  1037.        CALL   WRITE_DSP
  1038.  
  1039.        MOV    AL,_intr_num
  1040.        MOV    DX,OFFSET DMA_OUT_INTR
  1041.        MOV    BX,OFFSET DGROUP:ORG_INT_ADDX
  1042.        CALL   SETUP_INTERRUPT
  1043.  
  1044.        MOV    DX,[BP+BUF_SEG]
  1045.        MOV    AX,[BP+BUF_OFF]
  1046.        CALL   CALC_20BIT_ADDX
  1047.  
  1048.        MOV    DMA_CURRENT_PAGE,DL
  1049.        MOV    DMA_CURRENT_ADDX,AX
  1050.  
  1051.        MOV    CX,[BP+COUNT]
  1052.        MOV    LEN_L_TO_DMA,CX
  1053.        MOV    LEN_H_TO_DMA,0
  1054.  
  1055.        ADD    AX,[BP+COUNT]
  1056.        ADC    DL,0
  1057.        SUB    AX,1
  1058.        SBB    DL,0
  1059.  
  1060.        MOV    LAST_DMA_OFFSET,AX
  1061.        SUB    DL,DMA_CURRENT_PAGE
  1062.        MOV    PAGE_TO_DMA,DL
  1063.  
  1064.        CALL   DMA_OUT_TRANSFER
  1065.  
  1066.        SUB    AX,AX
  1067.  
  1068. OV90:
  1069.        POP    SI
  1070.        POP    DI
  1071.        POP    ES
  1072.        POP    DS
  1073.  
  1074.        POP    BP
  1075.        RET
  1076.  
  1077. _ctv_output      ENDP
  1078.  
  1079.  
  1080. ifdef  small
  1081.     _ctv_halt     PROC
  1082. else
  1083.     _ctv_halt     PROC     FAR
  1084. endif
  1085.  
  1086.        PUSH   DS
  1087.        PUSH   ES
  1088.        PUSH   DI
  1089.        PUSH   SI
  1090.  
  1091.        MOV    AX,DGROUP
  1092.        MOV    DS,AX
  1093.        MOV    ES,AX
  1094.  
  1095.        MOV    AX,1
  1096.  
  1097.        CMP    _voice_status,0
  1098.        JZ     TVP90
  1099.  
  1100.        CALL   PAUSE_DSP_DMA
  1101.        CALL   END_DMA_TRANSFER
  1102.  
  1103.        SUB    AX,AX
  1104.  
  1105. TVP90:
  1106.        POP    SI
  1107.        POP    DI
  1108.        POP    ES
  1109.        POP    DS
  1110.        RET
  1111.  
  1112. _ctv_halt     ENDP
  1113.  
  1114.  
  1115. ifdef  small
  1116.     _ctv_pause    PROC
  1117. else
  1118.     _ctv_pause    PROC     FAR
  1119. endif
  1120.  
  1121.        PUSH   DS
  1122.        PUSH   ES
  1123.        PUSH   DI
  1124.        PUSH   SI
  1125.  
  1126.        MOV    AX,DGROUP
  1127.        MOV    DS,AX
  1128.        MOV    ES,AX
  1129.  
  1130.        MOV    AX,1
  1131.  
  1132.        CMP    _voice_status,1
  1133.        JNE    PV90
  1134.  
  1135.        CALL   PAUSE_DSP_DMA
  1136.        SUB    AX,AX
  1137.  
  1138. PV90:
  1139.        POP    SI
  1140.        POP    DI
  1141.        POP    ES
  1142.        POP    DS
  1143.        RET
  1144.  
  1145. _ctv_pause    ENDP
  1146.  
  1147.  
  1148.  
  1149. ifdef  small
  1150.     _ctv_continue PROC
  1151. else
  1152.     _ctv_continue PROC  FAR
  1153. endif
  1154.  
  1155.        PUSH   DS
  1156.        PUSH   ES
  1157.        PUSH   DI
  1158.        PUSH   SI
  1159.  
  1160.        MOV    AX,DGROUP
  1161.        MOV    DS,AX
  1162.        MOV    ES,AX
  1163.  
  1164.        MOV    AX,1
  1165.  
  1166.        CMP    _voice_status,1
  1167.        JNE    CV90
  1168.  
  1169.        MOV    DX,_io_addx
  1170.        ADD    DL,0CH
  1171.  
  1172.        MOV    AL,DSP_CONT_DMA_CMD
  1173.        CALL   WRITE_DSP
  1174.        SUB    AX,AX
  1175.  
  1176. CV90:
  1177.        POP    SI
  1178.        POP    DI
  1179.        POP    ES
  1180.        POP    DS
  1181.        RET
  1182.  
  1183. _ctv_continue ENDP
  1184.  
  1185.  
  1186. ifdef  small
  1187.     _ctv_uninstall     PROC
  1188. else
  1189.     _ctv_uninstall     PROC  FAR
  1190. endif
  1191.  
  1192.        PUSH   DS
  1193.        PUSH   ES
  1194.        PUSH   DI
  1195.        PUSH   SI
  1196.  
  1197.        MOV    AX,DGROUP
  1198.        MOV    DS,AX
  1199.        MOV    ES,AX
  1200.  
  1201.        CMP    _voice_status,0
  1202.        JZ     UI90
  1203.  
  1204.        CALL   PAUSE_DSP_DMA
  1205.        CALL   END_DMA_TRANSFER
  1206.  
  1207.  
  1208. UI90:
  1209.        SUB    AL,AL
  1210.        CALL   ON_OFF_SPEAKER
  1211.  
  1212.        SUB    AX,AX
  1213.  
  1214.        POP    SI
  1215.        POP    DI
  1216.        POP    ES
  1217.        POP    DS
  1218.        RET
  1219.  
  1220. _ctv_uninstall     ENDP
  1221.  
  1222.  
  1223.     ;-----------------------------------------------------------
  1224.     ; usage:                                                   :
  1225.     ;        unint ctv_card_here()                              :
  1226.     ; description:                                             :
  1227.     ;    detect the Game Blaster or Sound Blaster Card and     :
  1228.     ;    the configuration                                     :
  1229.     ; entry:                                                   :
  1230.     ;   the global i/o addx, ct_io_addx must set to a default  :
  1231.     ;   value, 2x0H, before call.                              :
  1232.     ; exit:                                                    :
  1233.     ;   High Byte = 0                                          :
  1234.     ;   Low Byte format -                                      :
  1235.     ;      0000 0001  :   C/MS music exists                    :
  1236.     ;      0000 0010  :   FM music exists                      :
  1237.     ;      0000 0100  :   CTV Voice exists                     :
  1238.     ;-----------------------------------------------------------
  1239.  
  1240.  
  1241. ifdef small
  1242.     _ctv_card_here    PROC     near
  1243. else
  1244.     _ctv_card_here    PROC     far
  1245. endif
  1246.  
  1247.  
  1248.        PUSH   DS                       ; for multi data model, set DS to
  1249.        MOV    AX,DGROUP                ;  DGROUP segment
  1250.        MOV    DS,AX
  1251.  
  1252.        SUB    BX,BX                    ; assume Creative Card doesn't exist, 
  1253.                                        ;   return 0
  1254.     ;-----------------------------
  1255.     ;    detect Game Blaster     :
  1256.     ;-----------------------------
  1257.  
  1258.        MOV    DX,_io_addx           ; get default i/o addx
  1259.        ADD    DL,6                     ; write the test code to
  1260.        MOV    AL,CMS_TEST_CODE         ;   output port 2x6H
  1261.        OUT    DX,AL                    ; ...
  1262.        SUB    AL,AL
  1263.        ADD    DL,4                     ; read the data back from
  1264.        OUT    DX,AL
  1265.        IN     AL,DX                    ;   input port 2xAH
  1266.        CMP    AL,CMS_TEST_CODE         ; the same data ?
  1267.        JNE    CARD10                   ; no, try Sound Blaster Card
  1268.  
  1269.        SUB    DL,4                     ; to ensure, try inverse data
  1270.        MOV    AL,NOT CMS_TEST_CODE     ; output port 2x6H
  1271.        OUT    DX,AL                    ; ...
  1272.        SUB    AL,AL
  1273.        ADD    DL,4                     ; read the data back from
  1274.        OUT    DX,AL
  1275.        IN     AL,DX                    ;   input port 2xAH
  1276.        CMP    AL,NOT CMS_TEST_CODE     ; the same data ?
  1277.        JNE    CARD10                   ; no, try Sound Blaster Card
  1278.  
  1279.        MOV    BX,CMS_EXIST
  1280.        JMP    SHORT CARD50
  1281.  
  1282.     ;--------------------------------------
  1283.     ;    detect the Sound Blaster Card    :
  1284.     ;--------------------------------------
  1285. CARD10:
  1286.        CALL   RESET_DSP
  1287.        JNZ    CARD50
  1288.  
  1289. CARD40:
  1290.        MOV    DX,_io_addx
  1291.        ADD    DL,0CH
  1292.  
  1293.        MOV    AL,DSP_ID_CMD
  1294.        CALL   WRITE_DSP_TIME
  1295.        JC     CARD50
  1296.  
  1297.        MOV    AL,CMS_TEST_CODE
  1298.        CALL   WRITE_DSP_TIME
  1299.        JC     CARD50
  1300.  
  1301.        CALL   READ_DSP_TIME
  1302.        JC     CARD50
  1303.  
  1304.        CMP    AL,NOT CMS_TEST_CODE
  1305.        JNE    CARD50
  1306.  
  1307.        MOV    BX,CMS_EXIST + CTV_VOICE_EXIST
  1308.  
  1309.  
  1310.     ;-----------------------------
  1311.     ;    detect the FM Music     :
  1312.     ;-----------------------------
  1313. CARD50:
  1314.        MOV    AX,0001H                 ; reset the FM chip
  1315.        CALL   WRITE_FM
  1316.  
  1317.        MOV    AX,6004H                 ; mask of timer 1 & 2
  1318.        CALL   WRITE_FM
  1319.  
  1320.        MOV    AX,8004H                 ; reset irq and both timer flags
  1321.        CALL   WRITE_FM
  1322.  
  1323.        MOV    AL,0                     ; read for 3 msb clear
  1324.        CALL   WAIT_FM_STATUS
  1325.        JC     CARD90
  1326.  
  1327.        MOV    AX,0FF02H                ; write timer 1 count
  1328.        CALL   WRITE_FM
  1329.  
  1330.        MOV    AX,2104H                 ; start timer 1
  1331.        CALL   WRITE_FM
  1332.  
  1333.        MOV    AL,0C0H                  ; wait for irq and timer 1 end
  1334.        CALL   WAIT_FM_STATUS
  1335.        JC     CARD90
  1336.  
  1337.        MOV    AX,6004H                 ; mask of timer 1 & 2
  1338.        CALL   WRITE_FM
  1339.  
  1340.        MOV    AX,8004H                 ; reset irq and both timer flags
  1341.        CALL   WRITE_FM
  1342.  
  1343.        ADD    BX,FM_MUSIC_EXIST
  1344.  
  1345. CARD90:
  1346.        MOV    AX,BX
  1347.  
  1348.        POP    DS
  1349.        RET
  1350.  
  1351. _ctv_card_here    ENDP
  1352.  
  1353. ifdef  small
  1354.  
  1355.     _TEXT  ENDS
  1356. else
  1357.     CTV_TEXT     ENDS
  1358. endif
  1359.        END
  1360.  
  1361.  
  1362.  
  1363.